package cn.lingyangwl.agile.system.service.impl;

import cn.lingyangwl.agile.infra.*;
import cn.lingyangwl.agile.infra.module.misc.*;
import cn.lingyangwl.agile.system.assembly.*;
import cn.lingyangwl.agile.system.mapper.*;
import cn.lingyangwl.agile.system.model.entity.*;
import cn.lingyangwl.agile.system.model.rqrs.log.*;
import cn.lingyangwl.agile.system.service.*;
import cn.lingyangwl.framework.mybatis.plus.utils.*;
import cn.lingyangwl.framework.tool.core.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.time.LocalDateTime;
import java.util.*;
import java.util.stream.Collectors;

/**
 * 操作日志 服务层处理
 * 
 * @author shenguangyang
 */
@Service
public class SysAccessLogServiceImpl implements SysAccessLogService {
    @Resource
    private SysAccessLogMapper logMapper;
    @Resource
    private LogAssembly logAssembly;
    @Resource
    private InfraApi infraApi;

    /**
     * 新增操作日志
     * 
     * @param req 操作日志对象
     * @return 结果
     */
    @Override
    public boolean save(AccessLogSaveReq req) {
        Optional<Ip2RegionDto> ip2RegionDto = infraApi.ip2Region(req.getRequestIp());
        req.setLocation(ip2RegionDto.map(Ip2RegionDto::defaultFormat).orElse("-"));

        return logMapper.insert(logAssembly.toAccessLog(req)) > 0;
    }

    @Override
    public IPage<SysAccessLog> pageAccessLog(AccessLogPageReq req) {
        LocalDateTime beginTime = req.getBeginLocalDateTime();
        LocalDateTime endTime = req.getEndLocalDateTime();
        LambdaQueryWrapper<SysAccessLog> lqw =  SysAccessLog.lqw()
                .eq(StringUtils.isNotEmpty(req.getTraceId()), SysAccessLog::getTraceId, req.getTraceId())
                .like(StringUtils.isNotEmpty(req.getTag()), SysAccessLog::getTag, req.getTag())
                .eq(StringUtils.isNotEmpty(req.getStatus()), SysAccessLog::getStatus, req.getStatus())
                .ge(Objects.nonNull(beginTime), SysAccessLog::getCreatedAt, beginTime)
                .le(Objects.nonNull(endTime), SysAccessLog::getCreatedAt, endTime)
                .orderByDesc(SysAccessLog::getCreatedAt);
        
        IPage<SysAccessLog> pageRq = PageUtil.to(req);
        return logMapper.selectPage(pageRq, lqw);
    }

    /**
     * 查询系统操作日志集合
     * 
     * @param req 操作日志对象
     * @return 操作日志集合
     */
    @Override
    public List<SysAccessLog> listAccessLog(SysAccessLog req) {
        return logMapper.selectList(getLqw(req));
    }

    private LambdaQueryWrapper<SysAccessLog> getLqw(SysAccessLog rq) {
        return SysAccessLog.lqw()
                .eq(StringUtils.isNotEmpty(rq.getTraceId()), SysAccessLog::getTraceId, rq.getTraceId())
                .like(StringUtils.isNotEmpty(rq.getTag()), SysAccessLog::getTag, rq.getTag());
    }

    /**
     * 批量删除系统操作日志
     * 
     * @param logIds 需要删除的操作日志ID
     * @return 结果
     */
    @Override
    public boolean deleteBatch(Long[] logIds) {
        return logMapper.deleteBatchIds(Arrays.stream(logIds).collect(Collectors.toList())) == logIds.length;
    }

    /**
     * 查询操作日志详细
     *
     * @return 操作日志对象
     */
    @Override
    public SysAccessLog get(Long id) {
        return logMapper.selectById(id);
    }

    /**
     * 清空操作日志
     */
    @Override
    public void clear() {
        logMapper.cleanLog();
    }

    @Override
    public int deleteLogTask(String endTime) {
        LambdaQueryWrapper<SysAccessLog> wrapper = SysAccessLog.lqw()
            .le(SysAccessLog::getCreatedAt, endTime);
        return logMapper.delete(wrapper);
    }
}
